package eleventh.Runtime类;

public class 得到JVM的内存空间信息 {
    public static void main(String[] args) {
        Runtime run = Runtime.getRuntime();//通过静态方法为其实例化
        System.out.println("JVM最大内存量："+run.maxMemory());
        System.out.println("JVM空闲内存量："+run.freeMemory());
        String s = "Hello Java!!! Welcome to Runtime";
        System.out.println(s);
        for (int i = 0; i <50 ; i++) {
            s+=i;   //循环修改String，产生多个垃圾，会占用内存
        }
        //观察有多个垃圾空间产生后的内存空闲量
        System.out.println("操作String之后，JVM空闲内存量："+run.freeMemory());
        //进行垃圾收集
        run.gc();
        //垃圾收集之后的内存空闲量
        System.out.println("垃圾回收后，JVM空闲内存量："+run.freeMemory());
    }
}
/**
 * 垃圾回收之后，JVM空闲内存量没有完全恢复的原因可能有以下几点：
 *
 * 垃圾回收器没有将所有的垃圾对象进行回收。Java中的垃圾回收器并不总是能立即回收所有的垃圾对象，这取决于具体的垃圾回收策略和算法。
 * 例如，有些垃圾回收器可能会选择在内存使用达到一定阈值时才进行垃圾回收，或者只针对某些特定的内存区域进行回收。因此，即使进行了垃圾回收，
 * 也可能有部分垃圾对象没有被回收，导致JVM空闲内存量没有完全恢复。
 *
 * 对象分配和回收的开销。在Java中，对象的创建、分配和回收都会有一定的开销。当进行垃圾回收后，虽然大部分的垃圾对象已经被回收，
 * 但是仍然可能有一些新的对象被创建并占用了部分内存空间。这些新对象可能是由于程序运行过程中的其他操作导致的，比如创建新的字符串、数组等。
 * 因此，即使进行了垃圾回收，JVM空闲内存量也可能没有完全恢复。
 *
 * JVM内存管理机制的限制。JVM的内存管理机制包括堆内存和非堆内存的管理，其中堆内存主要用于存储对象实例，非堆内存主要用于存储类元数据、方法区等信息。
 * 垃圾回收主要针对堆内存进行，但是堆内存的管理也受到一定的限制。例如，JVM可能会将一部分堆内存预留给特定类型的对象，如大对象、长期存活的对象等，
 * 这部分内存不会被垃圾回收器回收，因此即使进行了垃圾回收，JVM空闲内存量也可能没有完全恢复。
 */

/**
 * 说明：这些可用内存不是固定的
 * 回答：Java中可用内存是可以调整的，但是在调整之前需要了解Java中的内存组成：主要是两部分：堆内存和非堆内存
 *      堆内存主要由于两部分组成：①年轻代和旧生代  ②存活空间
 *
 *  提示:垃圾回收处理与对象收集
 *      虽然垃圾收集只是通过一个gc()方法实现，但是垃圾回收与Java的内存划分也是有关系的。
 *      因为垃圾回收主要是对年轻代与旧生代的内存进行回收。
 *      年轻代内存空间用于存放新产生的对象，而经过若干次回收还没有被回收掉的对象向旧生代内存空间移动。
 *      对减轻带进行垃圾回收又称为MinorGC（从垃圾收集），对旧生代垃圾回收称为MajorGC（主垃圾收集），并且两块内存回收互不干涉。
 *      在JVM中的对象回收机制会使用一种分代回收的册罗，用较高的频率对年轻代对象进行扫描和回收，而对旧生代对象用较低的频率进行回收，
 *      这样就不需要在每次执行GC时将内存中的所有对象都检查一遍；
 *      对于GC的执行简单的可以描述为：当JVM剩余内存空间不足时，会触发GC，当Eden内存空间不足时，则进行Minor Collection；当旧生代空间不足时候，
 *      则进行主回收（Major Collection)；当永久代空间不足时，则进行完全垃圾回收（Full Collection）
 *
 *
 */